package org.janon.httpproxy.client.method;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.janon.httpproxy.HttpUtil;

public class ConnectReadMethod
{
	private Thread[] thread = new Thread[2];
	private BufferedInputStream[] server_in = new BufferedInputStream[2];
	private Socket[] socket = new Socket[2];
	private BufferedOutputStream client_out = null;
	
	public ConnectReadMethod(BufferedInputStream server_in, BufferedOutputStream client_out, Socket socket)
	{
		this.server_in[0] = server_in;
		this.socket[0]=socket;
		this.client_out = client_out;
		
		thread[0] = new Thread(HttpUtil.getThreadGroup(),new ConnectReadMethodThread(server_in,client_out,socket),"clientThread");
		thread[0].start();
	}
	
	public void setServerInputStream(BufferedInputStream server_in, Socket socket)
	{
		if(thread[1]!=null)
		{
			try
			{
				this.server_in[1].close();
				this.socket[1].close();
			}catch(Exception ex){}
		}
		this.thread[1]=this.thread[0];
		this.server_in[1]=this.server_in[0];
		this.socket[1]=this.socket[0];
		this.server_in[0]=server_in;
		this.socket[0]=socket;
		this.thread[0] = new Thread(HttpUtil.getThreadGroup(),new ConnectReadMethodThread(server_in,this.client_out,socket),"clientThread");
		this.thread[0].start();
	}
	
	@SuppressWarnings("deprecation")
	public void removeServerInputStreams()
	{
		if(thread[0]!=null)
		{
			try
			{
				this.server_in[0].close();
				this.socket[0].close();
			}catch(Exception ex){}
			try
			{
				this.socket[0].close();
			}catch(Exception ex){}
			try
			{
				this.thread[0].stop();
			}catch(Exception ex){}
		}
		if(thread[1]!=null)
		{
			try
			{
				this.server_in[1].close();
				this.socket[1].close();
			}catch(Exception ex){}
			try
			{
				this.socket[1].close();
			}catch(Exception ex){}
			try
			{
				this.thread[1].stop();
			}catch(Exception ex){}
		}
		thread[0]=null;
		thread[1]=null;
	}
	
	public boolean isClose()
	{
		return thread[0]==null && thread[1]==null;
	}
	
	public class ConnectReadMethodThread implements Runnable
	{
		private BufferedInputStream server_in = null;
		private BufferedOutputStream client_out = null;
		private Socket socket = null;
		private final int BUFFER_SIZE = 96000;
		public ConnectReadMethodThread(BufferedInputStream server_in, BufferedOutputStream client_out, Socket socket)
		{
			this.server_in = server_in;
			this.client_out = client_out;
			this.socket = socket;
		}
		
		public void run()
		{
			try
			{
				byte[] buf = new byte[BUFFER_SIZE];
				int bytes_read;
				while ((bytes_read = server_in.read(buf)) != -1)
				{
					if(!HttpUtil.startsWith(new String(buf, 0, bytes_read), "X-Trickling: "))
					{
						client_out.write(buf, 0, bytes_read);
						client_out.flush();
					}
				}
			}
			catch(Exception e)
			{
			}
			finally
			{
				try
				{
					server_in.close();
				}
				catch (IOException e) { }
				try
				{
					socket.close();
				}
				catch (IOException e) { }
			}
		}
	}

}
